package com.springboot.springmvc.restful.crud.advice;

import com.springboot.springmvc.restful.crud.common.R;
import com.springboot.springmvc.restful.crud.exception.BuzzException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;

/*
* 如果出现了异常：本类和全局都不能处理，
  * SpringBoot底层对SpringMVC有兜底处理机制；自适应处理（浏览器响应页面、移动端会响应json）
  * 最佳实践：我们编写全局异常处理器，处理所有异常
  * <p>
  * 前端关心异常状态，后端正确业务流程。
  * 推荐：后端只编写正确的业务逻辑，如果出现业务问题，后端通过抛异常的方式提前中断业务逻辑。前端感知异常；
*
*
*
*
*

 */
 @ResponseBody
@ControllerAdvice//全局异常处理
public class GlobalExceptionAdvice {
    @ExceptionHandler(Throwable.class)
    public R error(Throwable e){
        System.out.println("【全局】-Throwable");
        return R.error(500,e.getMessage());
    }
    @ExceptionHandler(Exception.class)
    public R error01(Exception e){
        System.out.println("【全局】-Exception");
        return R.error(300,e.getMessage());
    }

    @ExceptionHandler(ArithmeticException.class)
    public R error02(Exception e){
        System.out.println("【全局】-ArithmeticException");
        return R.error(100,e.getMessage());
    }
    //业务异常处理
    @ExceptionHandler(BuzzException.class)
     public R error03(BuzzException e){
        System.out.println("【全局】-BuzzException");
        return R.error(e.getCode(),e.getMsg());
    }
    //使用全局异常处理，处理请求参数校验异常
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
     public R error04(MethodArgumentNotValidException e){
        BindingResult result = e.getBindingResult();
        HashMap<String, String> errorsMap = new HashMap<>();
        for (FieldError fieldError : result.getFieldErrors()){
            //1.获取属性名
            String field = fieldError.getField();
            //2.获取错误信息
            String message = fieldError.getDefaultMessage();
            //3.将信息放入已存储好的map中
            errorsMap.put(field,message);
        }
        System.out.println("【全局】-MethodArgumentNotValidException");
        return R.error(500,"参数校验失败",errorsMap);
    }
}
